Используйте awk для строковой переменной - PullRequest
1 голос
/ 27 октября 2011

Просто запускаю довольно простой скрипт, но получаю ошибки, и я думаю, вероятно, это проблема с использованием awk для переменных. Может быть, я пропускаю некоторые основные уроки о awk Посмотрите на ниже:

#!/bin/bash
for((c=1;c<=542;c++))
do
    LINE=`head -$c FM_DEL_50r.bed|tail -1`
        cat $LINE|awk '{print $1" "$2" "$3}'

done

FM_DEL_50r.bed выглядит так:

chr1    3392391 3658426 DEL chr1    3392364 3658425 DEL
chr1    4011952 4392064 DEL chr1    4011953 4392062 DEL
chr1    4468526 4665322 DEL chr1    4468523 4665322 DEL
chr1    5759839 5997664 DEL chr1    5759836 5997664 DEL

Ошибка как:

cat: chr1: No such file or directory
cat: 3392391: No such file or directory
cat: 3658426: No such file or directory
cat: DEL: No such file or directory
cat: chr1: No such file or directory
cat: 3392364: No such file or directory
cat: 3658425: No such file or directory
cat: DEL: No such file or directory

Может кто-нибудь показать мне, в чем проблема? ТНХ

Ответы [ 3 ]

1 голос
/ 27 октября 2011

Крис ответил правильно, но, как вы спросили «в чем проблема с кодом» в вашем комментарии, проблема с вашим кодом состоит в том, что cat обычно ожидает имена файлов в качестве аргументов, и результат выполнения cat file1 file2 ... будет полное содержимое всех файлов, выгружаемых на ваш экран или в любые конечные конвейеры.

Если вы используете функцию отладки оболочки, set -vx перед циклом, вы увидите, как ваша $ LINE передается в виде списка файлов в cat и, конечно, вы можете увидеть это по полученным сообщениям

cat: chr1: No such file or directory
cat: 3392391: No such file or directory
....

Чтобы исправить ваш код, замените cat $LINE на echo "$LINE", чтобы оставить пробелы / табуляции как есть в выводе файла ИЛИ echo $LINE и получить один пробел между каждым словом в LINE.

Вы решили напечатать каждую строку, увеличив $c, поскольку head из вашего файла супер неэффективно. Вы должны прочитать файл полностью для каждой строки данных. Хотя для небольших файлов это будет работать нормально, если вы примените эту технику к файлу с тысячами строк, ваше время выполнения будет расти в геометрической прогрессии (извините, не точный прогноз) вместо того, чтобы обрабатывать файл менее чем за 1 секунду, занимает 100 или 1000 секунд.

(Хороший вопрос, я ценю пример данных. Это также помогло бы включить хотя бы одну или две строки ожидаемого результата.)

Надеюсь, это поможет.

1 голос
/ 27 октября 2011

Чтобы сделать это правильно в bash:

count=0
while read a b c rest_of_line; do
  echo $a $b $c
  (( ++count == 542 )) && break
done < FM_DEL_50r.bed

или, возможно,

head -542 FM_DEL_50r.bed | while read a b c rest_of_line; do echo $a $b $c; done
1 голос
/ 27 октября 2011

голова и хвост дадут вам строку из файл. Для вывода такой строки используйте «echo», cat используется для вывода содержимого потока или файла на стандартный вывод. Вот почему вы получаете сообщения об ошибках.

В любом случае, что ты пытаешься сделать? Вы пытаетесь прочитать в файле FM_DEL_50r.bed построчно и распечатывать столбцы 1, 2 и 3. Тогда попробуйте:

Команда:

awk 'NR<543{print $1 " " $2 " " $3}' x

Выход:

chr1 3392391 3658426
chr1 4011952 4392064
chr1 4468526 4665322
chr1 5759839 5997664
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...