Вы можете использовать команду read
для разделения полей. Поэтому вы должны установить для переменной разделителя полей значение ,
, чтобы указать, что поля разделены запятыми. Вы можете позже изменить его обратно, если вам нужно сделать что-то еще в сценарии:
#!/bin/bash
oldIFS=$IFS
IFS=,
while read a b c d e f g h i; do
echo "$a,$b,$c,$d,$(date -d"$e" +'%Y-%m-%d %H:%M:%S'),$f,$g,$h,$i"
done < "$1"
IFS=$oldIFS
(Это предполагает дату GNU, -d
, например, дата FreeBSD делает что-то другое.)
answer=spaghetti
guess=aeghipstt
# find the individual letters in the answer
# use an associative array to manage duplicates
declare -A letters=()
for ((i=0; i < ${#answer}; i++)); do
letters[${answer:i:1}]=1
done
# remove duplicate letters in the guess.
# could use the above technique, but here's another one
guess_uniq=$( sed 's/./&\n/g' <<< "$guess" | sort -u | tr -d '\n' )
# loop over the unique letters of the guess,
# and count how many letters are in the answer
matches=0
for ((i=0; i < ${#guess_uniq}; i++)); do
[[ ${letters[${guess_uniq:i:1}]} = "1" ]] && (( matches++ ))
done
if (( matches == ${#guess_uniq} )); then echo "Correct"; fi
Вот как это сделать в bash.
# ----------------------------------------------------------------------------
# INPUT:
# $1 answer (contains the "source" string)
# $2 guess (contains individual characters to be counted from $answer)
#
# OUTPUT:
# prints to standard output a count of the characters from 'guess' which
# appear in 'answer'
# ----------------------------------------------------------------------------
answer=$1
guess=$2
count=0
# for each character in $guess, observe whether its elimination from
# $answer causes the resultant string to be different; if so, it exists,
# therefore increment a counter
# iterate over the characters of $guess
for (( i=0; i < ${#guess}; i=i+1 )); do
current_char=${guess:$i:1}
# attempt to extract current character
answer_after_extract=${answer//$current_char}
# has $answer changed?
if [[ $answer_after_extract != $answer ]]; then
count=$(( count + 1 ))
fi
answer=$answer_after_extract
done
echo $count
ВЫВОД ОБРАЗЦА
$ ./answer spaghetti spgheti
7
$ ./answer abcdefghijklmnopqrstuvwxyz aeiou
5
$ ./answer abcdefghijklmnopqrstuvwxyz xyzzy
3
В Perl оператор транслитерации tr //
(который работает почти так же, как утилита оболочки tr
) возвращает количество символов, которые были транслитерированы.
$ perl -e 'print("spgheti" =~ tr/spaghetti/spaghetti/, "\n")'
7
Т.е. «семь символов в спгети
найдены в спагетти
».
$ perl -e 'print("spaghetti" =~ tr/spgheti/spgheti/, "\n")'
8
Т.е. «восемь символов в спагетти
найдены в spgheti
» (поскольку t
встречается дважды в спагетти
, он считается дважды).
Создание цикла вокруг этого:
while read word1 word2; do
perl -e 'printf("%s / %s: %d\n", $ARGV[0], $ARGV[1],
eval "$ARGV[0] =~ tr/$ARGV[1]/$ARGV[1]/")' "$word1" "$word2"
done <<LIST_END
stkflw Stackoverflow
fete feet
good goodness
par rap
LIST_END
Вызов Perl eval ()
необходим, чтобы иметь возможность вставить $ ARGV [1]
в список поиска и замены tr //
.
Вывод:
stkflw / Stackoverflow: 5
fete / feet: 4
good / goodness: 4
par / rap: 3
Или чтение из файла с двумя словами в каждой строке:
while read word1 word2; do
# as before
done <wordpairs