2013-01-25 1 views
0

Я хотел бы извлечь пути файлов из разных каталогов, перечисленных внутри файла после «FILE_PATHS», а затем извлечь определенную часть этих имен файлов на основе при условии. Например:Grep список файлов из файла и печать определенной части строки с условием

$ grep ^FILE_PATHS file.txt 
FILE_PATHS /james/families/MOTHER/analyses/trait 
FILE_PATHS /james/families/SIB/analyses/BROTHER/trait 
FILE_PATHS /james/families/REL/analyses/AUNT/trait 
FILE_PATHS /james/families/FATHER/analyses/trait 

Из этого списка путей к файлам, я хотел бы, чтобы извлечь определенную часть имени файла «МАМА», «SIB», «REL», «ОТЕЦ», а затем, если эта часть равен «SIB» print «BROTHER», если он равен «REL» печатать «AUNT», в противном случае (для «MOTHER» и «FATHER») напечатайте «MOTHER» и «ОТЕЦ». Единственные файлы, у которых есть путь, отличный от остальных, равны «SIB» и «REL» в 4-м поле, однако осложнение состоит в том, что существует много вариантов того, что может быть значением на 6-м поле, поэтому Я ищу решение, в котором мне не нужно указывать значения «BROTHER» и «AUNT» в 6-м поле, но это просто напечатает мое 6-е поле.

Так что было бы что-то вроде этого:

cat file.txt | while read line; do 
if [ `echo "$line" | grep ^FILE_PATHS file.txt | cut -d' ' -f 2 | cut -d '/' -f4 -eq "BROTHER" | "REL" ` ] 

then 
    grep ^FILE_PATHS file.txt | cut -d' ' -f 2 | cut -d '/' -f5 
else 
    grep ^FILE_PATHS file.txt | cut -d' ' -f 2 | cut -d '/' -f4 
fi; done 

Это полно ошибок и неправильно, но, может быть, у меня есть неправильный подход все вместе, и я уверен, что есть умный способ сделать это, но Я совершенно не знаком с BASH, есть ли лучший подход, которого я не вижу?

+0

Чтобы уточнить, хотите ли вы распечатать компонент * после * SIB или REL (что может быть, предположительно, SISTER или UNCLE или что-то еще)? – chepner

+0

Только компоненты, например: MOTHER, BROTHER, AUNT, FATHER .. – user1642995

ответ

0

это должно работать для вас

your grep....|awk -F/ '{$4=$4=="REL"?"AUNT":$4;$4=$4=="SIB"?"BROTHER":$4;print $4}' 

на самом деле вы могли бы объединить Grep в AWK как:

awk -F/ '/^FILE_PATHS/{$4=$4=="REL"?"AUNT":$4;$4=$4=="SIB"?"BROTHER":$4;print $4}' file.txt 

выход из вашего примера:

MOTHER 
BROTHER 
AUNT 
FATHER 

показать, как это работает:

kent$ cat o 
FILE_PATHS /james/families/MOTHER/analyses/trait 
FILE_PATHS /james/families/SIB/analyses/BROTHER/trait 
FILE_PATHS /james/families/REL/analyses/AUNT/trait 
FILE_PATHS /james/families/FATHER/analyses/trait 

kent$ awk -F/ '/^FILE_PATHS/{$4=$4=="REL"?"AUNT":$4;$4=$4=="SIB"?"BROTHER":$4;print $4}' o 
MOTHER 
BROTHER 
AUNT 
FATHER 

EDIT Опять

Если значение на 3-м поле SIB или REL Я хотел бы напечатать все, что в пятом поле

Я бы сказал, это должно быть четвёртым поле SIB/REL, а затем напечатать 6-е. так как первое поле FILE_PATHS.

теперь эта линия работает:

awk -F/ '/^FILE_PATHS/{$4=$4~"^(REL|SIB)$"?$6:$4;print $4}' file.txt 

тест !!:

kent$ cat o 
FILE_PATHS /james/families/MOTHER/analyses/trait 
FILE_PATHS /james/families/SIB/analyses/BROTHER/trait 
FILE_PATHS /james/families/REL/analyses/AUNT/trait 
FILE_PATHS /james/families/FATHER/analyses/trait 

kent$ awk -F/ '/^FILE_PATHS/{$4=$4~"^(REL|SIB)$"?$6:$4;print $4}' o 
MOTHER 
BROTHER 
AUNT 
FATHER 
+0

Привет, Кент, спасибо. Код дает мне МАТЕРИ, СИБ, РЕЛЬ, ОТЕЦ, хотя, хотя я бы хотел, чтобы МАТЬ, БРАТЬ, АУНТ, ОТЕЦ ... – user1642995

+0

@ user1642995 либо вы ошиблись, либо я неправильно написал код. Я получил ожидаемый результат здесь. :( – Kent

+0

Это моя ошибка, вероятно, в папках есть другие подкаталоги, поэтому все пути будут следующими: $ grep^FILE_PATHS file.txt FILE_PATHS/james/family/MOTHER/анализы/черты FILE_PATHS/james/family/SIB/анализы/BROTHER/trait FILE_PATHS/james/family/REL/analysis/AUNT/trait FILE_PATHS/james/family/FATHER/анализы/признак – user1642995

1

Easy с помощью sed просто захватить предпоследний каталог:

$ sed -r '/^FILE_PATHS/s#.*/(\w+)/.*#\1#' file 
MOTHER 
BROTHER 
AUNT 
FATHER 

Edit:, если это не всегда предпоследний каталог:

$ grep "^FILE_PATHS" file | egrep -o "(MOTHER|BROTHER|AUNT|FATHER)" 
MOTHER 
BROTHER 
AUNT 
FATHER 
+0

Привет, судо, спасибо, я просто использовал это в качестве примера, но пути к файлам не всегда предпоследней, но он меняется ... – user1642995

+0

Ваш вопрос должен отражать это, см. редактирование. Может ли несколько совпадений отображать одну строку i.e '/ james/family/MOTHER/AUNT/trait /'? –

+0

Хорошо, теперь я отредактирую. Нет, не существует/james/family/MOTHER/AUNT/trait /, в основном это только два значения «SIB» и «REL», которые действуют иначе, чем остальные, и имеют разные пути. – user1642995

0

Это предполагает, что вы не имеете любые буквы верхнего регистра, кроме слов, которые вы ищете:

sed '/^FILE_PATHS/!d; s/^FILE_PATHS//; s/[^A-Z]//g; s/^SIB\|REL//' filename 
Смежные вопросы