#linux #perl #unix #sed #awk
#linux #perl #unix #sed #awk
Вопрос:
Я хочу удалить текст после первого двоеточия :
(включительно) или заменить его ничем.
Например, 1:5:30
должно быть изменено на 1
. Я предпочитаю сценарий awk для выполнения этой работы. Но я не знаю, как это сделать. Не могли бы вы, пожалуйста, дать мне какие-либо указания? Заранее спасибо.
Мои данные разделены табуляцией, и файл выглядит так, как будто в некоторых ячейках есть точки.
1 313 . T C 30.11 1:5:30 . . .
1 316 . A T 30.80 1:5:30 . 0:8:28 .
1 317 . T A 31.40 1:5:36 . 0:8:28 .
Я попробовал следующее, но со всеми из них у меня ничего не вышло:
sed 's/:*:*//g' mydatafile
sed 's/:[0-9]:[0-9]//g' mydatafile
Комментарии:
1. Похоже, что есть много правильных ответов. Продолжайте и примите одно из них. Нажмите на «галочку», чтобы принять ответ
Ответ №1:
Немного неясно, каким должен быть желаемый результат, но это моя интерпретация, использующая sed
:
$ sed 's/:.*//' input
1 313 . T C 30.11 1
1 316 . A T 30.80 1
1 317 . T A 31.40 1
Использование awk:
$ awk -F":" '{print $1}' input
1 313 . T C 30.11 1
1 316 . A T 30.80 1
1 317 . T A 31.40 1
Используя Cut:
cut -d":" -f1 input
Использование bash:
IFS=':'
while read a b; do
echo $a
done < input
Альтернативная интерпретация с использованием awk:
$ awk 'BEGIN {OFS="t"} {sub(/:.*/,"",$7); print}' input
1 313 . T C 30.11 1 . . .
1 316 . A T 30.80 1 . 0:8:28 .
1 317 . T A 31.40 1 . 0:8:28 .
3-е и, надеюсь, последнее обновление
третья интерпретация с использованием awk:
$ awk 'BEGIN {OFS="t"} {for (i=1;i<NF;i ){sub(/:.*/,"",$i)}; print}' input
1 313 . T C 30.11 1 . . .
1 316 . A T 30.80 1 . 0 .
1 317 . T A 31.40 1 . 0 .
Комментарии:
1. Дорогой Фредрик, очень хорошие скрипты sed / bash / awk. Большое спасибо. На самом деле, я хочу, чтобы все ячейки с таким шаблоном (integers_1: integers_2: integers_2) были заменены на integer_1.
2. @jianfeng.mao было бы хорошо, если бы вы могли обновить свой вопрос списком правильных выходных данных. Я сделал 2 интерпретации, и обе были неправильными 😉
Ответ №2:
perl -p -e 's/:d :d //g' mydatafile
Комментарии:
1. Уважаемый FMc, большое спасибо. Я не могу понять perl. Но я узнал, что это мощное средство из вашего скрипта.
Ответ №3:
Попробуйте это:
sed 's/([0-9][0-9]*):[0-9][0-9]*:[0-9][0-9]*/1/g' infile
или
sed 's/([0-9]{1,}):[0-9]{1,}:[0-9]{1,}/1/g' infile
Вывод:
1 313 . T C 30.11 1 . . .
1 316 . A T 30.80 1 . 0 .
1 317 . T A 31.40 1 . 0 .
Ответ №4:
Вот самый короткий вариант, использующий sed
:
sed -i.orig 's/([0-9])*:[^ ]*/1/g' inputfile
При этом сохраняется копия исходного файла как inputfile.orig
. И заменяет файл на месте.
Ответ №5:
Это должно сработать.
$ sed -e 's/:.*//' mydatafile
1 313 . T C 30.11 1
1 316 . A T 30.80 1
1 317 . T A 31.40 1
Я думаю, что sed немного проще, чем awk, для решения этой проблемы.
Обзор синтаксиса регулярных выражений
Позже . . .
Из ваших комментариев к другим ответам я вижу, что вы хотите заменить каждое вхождение x:y:z
на x
. В таком случае я бы использовал эту awk-программу.
$ cat test.awk
BEGIN {
FS = "t";
}
{
for (i = 1; i <= NF; i ) {
if (match($i, /:.*/)) {
$i = substr($i, 1, RSTART - 1);
}
printf("%st", $i);
}
printf("n");
}
$ awk -f test.awk test.dat
1 313 . T C 30.11 1 . . .
1 316 . A T 30.80 1 . 0 .
1 317 . T A 31.40 1 . 0 .
Комментарии:
1. Дорогой Кэтколл, большое спасибо. Я пока пытаюсь понять ваш скрипт.
2. @jianfeng.mao: Он просто заменяет двоеточие, за которым следует ноль или более символов, на ничто.