Вот решение, использующее просто awk
. Поместите ниже кода в названном файле ex.awk
:
BEGIN{}
FNR==NR{
k=$1" "$2
a[k]=$4" "$5
b[k]=$0
c[k]=$4
d[k]=$5
next
}
{ k=$1" "$2
lc=c[k]
ld=d[k]
# file1 file2
if ((k in a) && ($4==$5) && (lc==$4) || (ld==$5)) print b[k]" "$0
}
И затем выполненный это как это с вышеупомянутыми 2 файлами:
$ awk -f ex.awk file1 file2
sed
должен только отформатировать вывод для StackExchange!
$ awk -f ex.awk file1 file2 | sed 's/[ ]\+/ /g'
s2/90 60 . C G 30 N=2 F=5;U=4 s2/90 60 . G G 97 N=2 F=5;U=4
s2/80 20 . A T 86 N=2 F=5;U=4 s2/80 20 . A A 20 N=2 F=5;U=4
s2/20 10 . G T 90 N=2 F=5;U=4 s2/20 10 . G G 99 N=2 F=5;U=4
OP упомянул в комментариях, ниже которых он хотел бы, чтобы окончательное решение отбросило любые строки где 4-е и 5-е столбцы от file1
подобранный 4-е и 5-е столбцы от file2
.
Например, добавьте эту строку к обоим file1
& file2
:
s2/40 40 . S S 90 N=2 F=5;U=4
Однострочное дополнение к исходному решению может обратиться к этому конкретному изменению в требованиях.
if ((k in a) && (lc==$4) && (ld==$5)) next
ex2.awk
:
BEGIN{}
FNR==NR{
k=$1" "$2
a[k]=$4" "$5
b[k]=$0
c[k]=$4
d[k]=$5
next
}
{ k=$1" "$2
lc=c[k]
ld=d[k]
if ((k in a) && (lc==$4) && (ld==$5)) next
if ((k in a) && ($4==$5) && (lc==$4) || (ld==$5)) print b[k]" "$0
}
Повторное выполнение нового awk
сценарий, ex2.awk
:
$ awk -f ex2.awk file1 file2 | sed 's/[ ]\+/ /g'
s2/90 60 . C G 30 N=2 F=5;U=4 s2/90 60 . G G 97 N=2 F=5;U=4
s2/80 20 . A T 86 N=2 F=5;U=4 s2/80 20 . A A 20 N=2 F=5;U=4
s2/20 10 . G T 90 N=2 F=5;U=4 s2/20 10 . G G 99 N=2 F=5;U=4
Выполните cat -v LIST
, чтобы увидеть, есть ли какие-либо специальные символы, которые вы не видите с помощью простого эха. Я подозреваю, что строки в DOS заканчиваются, то есть из-за посторонних переводов каретки перед новой строкой.
РЕДАКТИРОВАТЬ: преобразовать файл СПИСКА:
dos2unix < LIST > LIST.new && mv LIST.new LIST
Или, если у вас нет dos2unix, но есть vim: vim LIST
, затем : установите notx
, затем : wq
Следующие действия работают:
$ mkdir /tmp/test
$ cd /tmp/test
$ cat > LIST << EOD
> IMG_9324.JPG
> IMG_9329.JPG
> IMG_9463.JPG
> IMG_9412.JPG
> IMG_9562.JPG
> IMG_9511.JPG
> IMG_9607.JPG
> EOD
$ mkdir e
$ touch e/IMG_9607.JPG
$ touch e/IMG_9412.JPG
$ find .
.
./e
./e/IMG_9412.JPG
./e/IMG_9607.JPG
./LIST
$ for i in `cat LIST`; do find e/ -name "$i"; done
e/IMG_9412.JPG
e/IMG_9607.JPG
$
Поэтому начните с вышеизложенного, затем замените LIST действительным, а затем e /
. Если вы не достигли внутреннего предела Bash для цикла for (который должен вызвать ошибку), вы, должно быть, делаете что-то еще не так, чего нет в выходных данных вашего примера.
Cloud вы предоставляете образец списка файлов в папке / mnt / c / e-m10 /?
А пока не могли бы вы попробовать следующую команду?
for i in `cat LIST`; do echo $i; find /mnt/c/e-m10/ -iname $i -print; done
Она также распечатает любую информацию по мере необходимости, также игнорируя чувствительность к регистру.