Добавление столбца значений в файл с разделителями табуляции


17

Как я могу добавить столбец значений в файл, который имеет определенное количество строк. У меня есть входной файл, как это:

Входной файл:

SPATA17 1   217947738
LYPLAL1 1   219383905
FAM47E  4   77192838
SHROOM3 4   77660162
SHROOM3 4   77660731
SHROOM3 4   77662248

Выходной файл:

SPATA17 1   217947738 file1
LYPLAL1 1   219383905 file1
FAM47E  4   77192838  file1
SHROOM3 4   77660162  file1
SHROOM3 4   77660731  file1
SHROOM3 4   77662248  file1

В этом случае я хочу добавить Столбец значений до количества строк в файле. Значение остается неизменным, например «file1».

Причина в том, что у меня есть 100 таких файлов. Я не хочу открывать каждый файл и вставлять столбец. Также есть ли способ автоматизировать это, перейдя в каталог и добавив столбец значений. Значение берется из имени файла, которое должно быть добавлено в каждую строку файла в последнем / первом столбце.

Ответы:


22

Вы можете использовать однолинейный цикл следующим образом:

for f in file1 file2 file3; do sed -i "s/$/\t$f/" $f; done

Для каждого файла в списке это будет использоваться sedдля добавления в конец каждой строки вкладки и имени файла.

Объяснение:

  • Использование -iфлага с sedдля выполнения замены на месте, перезаписи файла
  • Выполните замену с помощью s/PATTERN/REPLACEMENT/. В этом примере PATTERN - $это конец строки, а REPLACEMENT - это \t(= TAB) и $fэто имя файла из переменной цикла. Команда s///находится в двойных кавычках, так что оболочка может раскрывать переменные.

Код работает. Можете ли вы объяснить содержание в кавычках?
Рон

Так же, как «awk» используется при работе со столбцами, «sed» также используется для аналогичных ситуаций. Я новичок в «awk» и «sed».
Рон

@Ron sedнаиболее удобен для замены шаблонов и сохранения на месте. Для вашего требования сохранения файла это был относительно удобный вариант. Если вам не нужно записывать обратно в тот же файл, который вы обрабатываете, то awkобычно с ним гораздо проще работать.
Janos

Лично меня awkслишком часто отключают входные / выходные разделители полей, поэтому я стараюсь по возможности избегать его использования, делая его sedболее привлекательным.
user5359531

11

Давай, почему вы, ребята, рекомендуете эти мощные инструменты, когда есть pasteкоманда!

$ cat a
A
B
C
D
$ cat b
1
2
3
4
$ paste a b
A   1
B   2
C   3
D   4

С небольшой хитростью, вы можете использовать pasteдля целей ОП. Тем не менее, он не заменит файлы на месте:

for f in file1 file2 file3; do 
    paste $f <(yes $f | head -n $(cat $f | wc -l)) > $f.new
done

Это вставит соответствующее имя файла в качестве последнего столбца каждого файла в новый файл filename.new


Благодарность! pasteбезусловно, скрытый драгоценный камень.
neu242

10

Вы можете использовать awk:

awk '{print $0, FILENAME}' file1 file2 file3 ...

Поскольку у каждого файла свое имя, я должен сделать это 100 раз. Есть ли способ сделать это один раз?
Рон

Нет, FILENAMEэто переменная awk, она расширяется до текущего имени файла, который awkобрабатывается. Вы просто делаете это один, кормить все файлы awk.
cuonglm

Хорошо, но как направить вывод в новый файл каждого файла? Сохраняет ли awk каждый файл при обработке?
Рон

Если у вас есть GNU awk 4.1.0или позже, вы можете использовать -iдля редактирования на месте. В противном случае вы должны перенаправить awkвывод в временный файл, а затем использовать grepдля извлечения строки из каждого файла.
cuonglm

Ну, вы можете сделатьfor file in *; do awk 'BEGIN{OFS="\t"}{print $0, FILENAME}' $file; done
Федорки
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.