Значення, розділені табуляцією в awk


90

Як вибрати перший стовпець із рядка, розділеного табуляцією?

# echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk -F'\t' '{print $1}'

Вищезазначене поверне весь рядок, а не лише "LOAD_SETTLED", як очікувалося.

Оновлення:

Мені потрібно змінити третій стовпець у значеннях, розділених табуляцією. Наступне не працює.

echo $line | awk 'BEGIN { -v var="$mycol_new" FS = "[ \t]+" } ; { print $1 $2 var $4 $5 $6 $7 $8 $9 }' >> /pdump/temp.txt

Однак це працює, як очікувалося, якщо роздільник замість табуляції ставиться комою.

echo $line | awk -v var="$mycol_new" -F'\t' '{print $1 "," $2 "," var "," $4 "," $5 "," $6 "," $7 "," $8 "," $9 "}' >> /pdump/temp.txt

4
awk 'BEGIN {FS = "[\ t] +"}; {print $ 1} '# це те, що я шукав. Чи правильний мій пошук у Google? :)
shantanuo

3
Завдяки цьому коментарю я виявив: awk 'BEGIN {FS="\t"}; {print $1,FS,$2,FS,$3}' myFile.txtдля друку значень перших трьох стовпців, розділених табуляцією.
Вок,

6
Або, можливо, простоawk 'BEGIN {OFS="\t"}; {print $1,$2,$3}'
Джосія Йодер

3
Підтримка GNU і BSD awk -vдля встановлення змінних. Потворно використовувати BEGIN {FS="\t"}всередині вбудованої програми , і проти будь-якого внеску з відкритим кодом, який ви намагаєтесь зробити, є заперечення. Робіть це лише в тому випадку, якщо ви пишете файл програми . Крім того, не рекомендується використовувати -Fзамість цього, -v FS=оскільки останній чітко дає зрозуміти, що лише FSвстановлюється, а ні OFS. Плутанина щодо цього останнього моменту - це те, що спричинило цю публікацію в першу чергу. Тому важливий «хороший стиль».
Бруно Броноскі

1
Будь ласка, ніхто і ніколи не повинен робити те, що демонстрував @Wok. Ви не перераховуєте розділювачі полів [Input] у своєму результаті. Ви визначаєте роздільник поля виводу за допомогою OFSзмінної.
Бруно Броноскі

Відповіді:


141

Вам потрібно встановити OFSзмінну (роздільник поля виводу) як вкладку:

echo "$line" | 
awk -v var="$mycol_new" -F $'\t' 'BEGIN {OFS = FS} {$3 = var; print}'

(переконайтеся, що ви вказали $lineзмінну в операторі echo)


6
Яка мета $ in $ '\ t'?
Амр Мостафа

10
Відповідаючи на моє власне запитання з Advanced Bash Scripting Guide : Конструкція розширення рядків із цитатою $ '... - це механізм, який використовує екрановані восьмеричні чи шістнадцяткові значення ..., наприклад, quote = $' \ 042 '.
Амр Мостафа

5
@AmrMostafa, дуже погано , що керівництво має оману пояснення веде до думки , що ви не $в $'\t'не потрібні. Вікі Грега краще: "З них $'...'найпоширеніший і діє так само, як одинарні лапки, за винятком того, що комбіновані зі зворотною рискою лінії розширюються відповідно до стандарту ANSI C."
Крістіан Джупіту

9
З огляду на минуле, $'\t'це не потрібно. awk розуміє, що рядок "\t"є символом табуляції
glenn jackman

5
Співавтори з відкритим кодом, прошу вас, не подавайте подібні речі awk -F $'\t' 'BEGIN {OFS = FS} …'. Це повинно бути awk -v FS='\t' -v OFS='\t' '…'. Це може здатися педантичним, але непослідовність збільшує шанси того, що пізніше співавтор внесе помилку, оскільки неправильно зрозумів ваш код.
Бруно Броноскі

21

Переконайтесь, що це справді вкладки! У bash ви можете вставити вкладку за допомогоюC-v TAB

$ echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk -F$'\t' '{print $1}'
LOAD_SETTLED


9

Я використовую змінні FSand та OFSдля обробки файлів зони BIND, які розділені табуляцією. Ось один із моїх сценаріїв https://gist.github.com/RichardBronosky/abe1652c2d5c78c35b92ad02bdf0d0af#file-dns_update-sh-L36-L39

М'ясо його:

awk -v FS='\t' -v OFS='\t' \
    -v record_type=$record_type \
    -v hostname=$hostname \
    -v ip_address=$ip_address '
$1==hostname && $3==record_type {$4=ip_address}
{print}
' $zone_file > $temp

Це чистий і легкий для читання спосіб зробити це.


5
echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk -v var="test" 'BEGIN { FS = "[ \t]+" } ; { print $1 "\t" var "\t" $3 }'

0

Це не повинно працювати?

echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk '{print $1}'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.