напечатать все, кроме выбора полей в awk - PullRequest
12 голосов
/ 23 июня 2011

У меня есть большой файл с сотнями столбцов, из которого я хочу удалить только третий и четвертый столбцы и распечатать остальные в файл.Моя первоначальная идея заключалась в том, чтобы сделать сценарий awk вроде awk '{print $1, $2, for (i=$5; i <= NF; i++) print $i }' file > outfile.Однако этот код не работает.

Затем я попытался:

awk '{for(i = 1; i<=NF; i++)
if(i == 3 || i == 4) continue
else
print($i)}' file > outfile

Но это просто распечатало все в одном поле.Можно было бы разбить это на два сценария и объединить их с Unix paste, но это похоже на то, что должно быть в состоянии сделать в одной строке.

Ответы [ 6 ]

15 голосов
/ 23 июня 2011

Ваша первая попытка была довольно близка. Модификация его для использования printf и включение разделителей полей работали для меня:

awk '{printf $1FS$2; for (i=5; i <= NF; i++) printf FS$i; print NL }'
9 голосов
/ 23 июня 2011

Что-то вроде:

cat SOURCEFILE | cut -f1-2,5- >> DESTFILE

Он печатает первые два столбца, пропускает 3-й и 4-й и затем печатает с 5 и далее до конца.

7 голосов
/ 23 июня 2011

Скажем, у вас есть файл с разделителями с разделителями, который выглядит следующим образом:

temp.txt

поле1 поле2 поле3 поле4 поле5 поле6
поле1 поле2 поле3 поле4 поле5 поле6
поле1 поле2 поле3 поле4 поле5 поле6

выполнение следующего удалит поля 3 и 4 и выведет их в конец строки.

awk '{print $1"\t"$2"\t"substr($0, index($0,$5))}' temp.txt

поле1 поле2 поле5 поле6
поле1 поле2 поле5 поле6
поле1 поле2 поле5 поле6

Мои примеры печатаются на стандартный вывод. > newFile отправит стандартный вывод в новый файл, а >> newFile добавит в новый файл.

Так что вы можете использовать следующее:

awk '{print $1"\t"$2"\t"substr($0, index($0,$5))}' temp.txt > newFile.txt

некоторые поспорят за сокращение

cut -f1,2,5- temp.txt

, которые выдают одинаковый результат, и cut отлично подходят для простоты, но не обрабатывают несовместимые разделители. Например, смесь разных пробелов. Тем не менее, в этом случае сокращение может быть то, что вы после.

Вы также можете выполнить это в perl, python, ruby ​​и многих других, но вот самое простое решение awk.

2 голосов
/ 18 марта 2013

Да, можно просто установить третий и четвертый столбцы в пустую строку; но, кроме того, поле $1 должно быть установлено на себя ($1=$1), чтобы awk фактически потребляло разделитель входного поля (разделитель) : на всей текущей строке $0 за один раз.

echo 1:2:3:4:5:6:7:8:9:10 | awk -F: '{ $1=$1; $3=""; $4=""; print $0}'
2 голосов
/ 23 июня 2011

Как насчет установки третьего и четвертого столбцов в пустую строку:

echo 1 2 3 4 5 6 7 8 9 10 |
awk -F" " '{ $3="";  $4=""; print}'
0 голосов
/ 06 августа 2015

Сложный, но общий способ (не говоря уже о простом oneliner)

awk -v "Exclude=3:4:5" '
   # load exclusion
   BEGIN{
      Count=split(Exclude, aTmp, ":")
      for( i = 1; i <= Count; i++) aExc[ aTmp[ i]]=1
      }

   # treat each line, taking only wanted field
   {
    Result=""
    for( i = 1; i <= NF; i++) {
       # field to take ?
       if( ! aExc[ i]) {
         # first element or add a separator before
         if( Result != "") Result=Result OFS $i
          else Result=$i
         }
       }

    print Result
   }' YourFile
  • вы можете указать любое поле, которое хотите исключить
    • заполнить индекс поля в varaible Исключить , разделить : в первой строке
  • правильные разделители на месте, количество
  • код "расширен" для лучшего понимания
  • конечный результат не совсем как входной (без исключенного поля), поскольку вместо исходного разделителя используется выходной разделитель (например, пробел 2 или вкладка заменяется на 1 пробел с поведением по умолчанию)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...