#linux #bash #unix
#linux #bash #unix
Вопрос:
Привет, я пытаюсь сравнить две строки в каталоге. формат следующий.
{sametext}difference{sametext}
.
Примечание: {sametext} не является статическим для каждого файла
например
myfile_1_exercise.txt
по сравнению с myfile_2_exercise.txt
Можете ли вы сказать мне, как бы я сопоставил приведенные выше строки в операторе if.
В принципе, мне нужно знать, как я мог бы игнорировать число в двух строках, чтобы они были одинаковыми.
Ниже приведен некоторый пример кода:
Мой пример кода выглядит следующим образом:
for g in `ls -d */`;
do
if [ -d $g ]; then
cd $g # down 1 directories
for h in `ls *root`;
do
printf "${Process[${count}]} = ${basedir}/${f}${g}${h}n"
h1=${h}
if [ "${h1}" = "${h2}" ]; then # NEED to MATCH SOME HOW??????????
echo we have a match
fi
h2=${h1}
let count =1
done
cd ../
#printf "nnnn"
fi
done
Каким должен быть тест, чтобы определить это вместо "${h1}" = "${h2}"
?
Приветствия,
Майк
Комментарии:
1. Когда вы говорите
strings in a directory
, вы на самом деле имеете в виду имена файлов?2. Я прочитал ваш пост 3 раза и до сих пор понятия не имею, о чем вы спрашиваете.
3. Будет ли
{sametext}
часть зависеть от файла, или это какое-то статическое значение, подобноеmyfile
? Другими словами, вы бы смотрели только на файлы, которые начинаются сmyfile
… ?4. Ваш тест «$ {h1}» = «$ {h2}» должен отлично работать для сравнения строк с помощью команды test (также известной как левая квадратная скобка). Но, конечно, h2 пуст при первом просмотре.
5. Извините, но {sametext} не является статичным.
Ответ №1:
"myfile_1_exercise.txt" == "myfile_2_exercise.txt"
Вы имеете в виду, что приведенный выше тест должен возвращать true
(игнорируя числа), верно?
Это то, что я бы сделал:
h1="myfile_1_exercise.txt"
h2="myfile_2_exercise.txt"
if [ $( echo ${h1} | sed 's/[0-9]*//g' ) == $( echo ${h2} | sed 's/[0-9]*//g' ) ] ; then
# do something here.
fi
Ответ №2:
sed
здесь пригодится.
Это в основном перебирает каждый файл в каталоге, извлекает две строки из имени файла и сохраняет список всех их уникальных комбинаций.
Затем он проходит по этому списку и использует расширение bash с подстановочными знаками, чтобы позволить вам перебирать каждую коллекцию.
РЕДАКТИРОВАТЬ: Избавился от уродливого взлома.
i=0
for f in *_*_*.txt
do
a=`echo "$f" | sed 's/(.*)_.*_(.*).txt/1/g'`
b=`echo "$f" | sed 's/(.*)_.*_(.*).txt/2/g'`
tmp=${all[@]}
expr match "$tmp" ".*$a:$b.*" >/dev/null
if [ "$?" == "1" ]
then
all[i]="$a:$b"
let i =1
fi
done
for f in ${all[@]}
do
a=`echo "$f" | sed 's/(.*):(.*)/1/g'`
b=`echo "$f" | sed 's/(.*):(.*)/2/g'`
echo $a - $b
for f2 in $a_*_$b.txt
do
echo " $f2"
# ...
done
done
Конечно, это предполагает, что все файлы, о которых вы заботитесь, следуют *_*_*.txt
шаблону.
Ответ №3:
Отказ от ответственности:
- Время выполнения может варьироваться, и вам, возможно, придется настраивать и отлаживать скрипт для угловых случаев.
- Возможно, вам лучше использовать Perl для вашей задачи.
- Могли бы быть лучшие решения даже в Bash. Это не очень эффективно, но, похоже, работает.
Как уже говорилось, вот скрипт, который сравнивает две строки в соответствии с вашими требованиями. Я уверен, что вы можете понять, как использовать это в вашем скрипте со списком каталогов (для которого вы, возможно, захотите рассмотреть find
кстати)
Этот скрипт берет две строки и выводит совпадение! если они совпадают
$ bash compare.sh myfile_1_exercise.txt myfile_2_exercise.txt
match!
$ bash compare.sh myfile_1_exercise.txt otherfile_2_exercise.txt
$
Сценарий:
#!/bin/bash
fname1=$1
fname2=$2
findStartMatch() {
match=""
rest1=$1 ;
rest2=$2 ;
char1=""
char2=""
while [[ "$rest1" != "" amp;amp; "$rest2" != "" amp;amp; "$char1" == "$char2" ]] ; do
char1=$(echo $rest1 | sed 's/(.).*/1/');
rest1=$(echo $rest1 | sed 's/.(.*)/1/') ;
char2=$(echo $rest2 | sed 's/(.).*/1/');
rest2=$(echo $rest2 | sed 's/.(.*)/1/') ;
if [[ "$char1" == "$char2" ]] ; then
match="${match}${char1}"
fi
done
}
findEndMatch() {
match=""
rest1=$1 ;
rest2=$2 ;
char1=""
char2=""
while [[ "$rest1" != "" amp;amp; "$rest2" != "" amp;amp; "$char1" == "$char2" ]] ; do
char1=$(echo $rest1 | sed 's/.*(.)/1/');
rest1=$(echo $rest1 | sed 's/(.*)./1/') ;
char2=$(echo $rest2 | sed 's/.*(.)/1/');
rest2=$(echo $rest2 | sed 's/(.*)./1/') ;
if [[ "$char1" == "$char2" ]] ; then
match="${char1}${match}"
fi
done
}
findStartMatch $fname1 $fname2
startMatch=$match
findEndMatch $fname1 $fname2
endMatch=$match
if [[ "$startMatch" != "" amp;amp; "$endMatch" != "" ]] ; then
echo "match!"
fi
Ответ №4:
Если вы на самом деле сравниваете два файла, как вы упомянули… вероятно, вы можете использовать diff
команду типа
diff myfile_1_exercise.txt myfile_2_exercise.txt
Комментарии:
1. Извините, Рахул, я сравниваю имена файлов. Не содержимое файла. Извините, я должен был быть более ясным