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


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.