Bash Сравнивает строки в каталоге

#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:

Отказ от ответственности:

  1. Время выполнения может варьироваться, и вам, возможно, придется настраивать и отлаживать скрипт для угловых случаев.
  2. Возможно, вам лучше использовать Perl для вашей задачи.
  3. Могли бы быть лучшие решения даже в 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. Извините, Рахул, я сравниваю имена файлов. Не содержимое файла. Извините, я должен был быть более ясным