如何在后面的bash中使用相同的单词但带有数字来更改单词

  • 本文关键字:单词 数字 bash 在后面 bash
  • 更新时间 :
  • 英文 :


我有一个文件名为file.csv的文件,内容为

adult,REZ
man,BRB
women,SYO
animal,HIJ

和既不是目录也不是文件的行

file.csv SYO2 REZ3 BRB1

我想做的是用这一行的单词改变文件的内容,然后得到这个单词的第n个字母,这些单词末尾的数字是大写的然后输出应该是

umo

代码如下所示

#!/bin/bash
filename="$1"
string=""
for i in "${@:2}"
do
words=$(echo "$i" | grep -oE '[A-Z]+')
number=$(echo "$i" | grep -oE '[0-9]+')
string+=$(echo "$words|")
numbers+=$(echo "$number|")
done
string=${string%|*}
numbers=${numbers%|*}
while IFS= read -r line
do
line1=$(echo $line | grep -oE $string)
if [[ -n $line1 ]] 
then 
echo $line 
fi
done < $filename

但是我得到输出

man, BRB
adult, REZ
women, SYO

,输出应为

umo

我不知道如何改变大写单词与它们相关联的数字,并且顺序不再相同。我如何改变这一点,或者我需要添加什么?

您没有在您尝试的任何地方处理所请求索引的子字符串/字符。你必须将键/标签与你想要的字符的偏移量联系起来,并以某种方式拉出那个字符。

我使用查找表。

#!/bin/bash
case $# in 0|1) echo "Use: $0 <infile> [search_pattern1[..search_patternN]]" >&2; exit 1;; esac
declare -A offset=()
for arg in "${@:2}"
do if [[ "$arg" =~ ^([A-Z]+)([0-9]+)$ ]]
then offset[${BASH_REMATCH[1]}]=$(( ${BASH_REMATCH[2]} - 1 ))
else echo "Argument '$arg' is not a valid search prameter."; exit 1
fi
done
while IFS=, read -r str tag
do [[ -n "${offset[$tag]}" ]] && printf "%s" "${str:${offset[$tag]}:1}"
done < "$1"
echo

我还添加了一些错误检查和说明。

还有很多其他方法可以做到这一点,例如并行数组,扫描匹配并使用相同的索引查找偏移量,但显然您希望记录被解析并输出,因此这是快速且相当容易的。

这是Awk的一个变体。我假设你想在这种格式中读取多个输入行。

while read file args; do
echo "$args" |
awk 'NR==FNR { split($0, b, ","); a[b[2]] = b[1]; k[b[2]] = ++m; next }
{ delete r; for(i=1; i<=NF; ++i) {
g=$i; sub(/[0-9]+$/, "", g);
n=substr($i, length(g)+1);
r[k[g]] = substr(a[g], n, 1);
}
for(j=1; j<=i; j++) if (r[j]) printf "%s", r[j];
printf "n"}' "$file" -
done

我假设输出应该按照字符在输入文件中出现的顺序,这是一个复杂的问题。辅助阵列k跟踪输入顺序,最后的for循环然后按该顺序输出结果。

#! /usr/bin/env bash
# Read first parameter
declare -r filename="$1"
shift
# Read other parameters
declare string=
declare number=
declare -a strings=()
declare -a numbers=()
# For each parameters
for i in "${@}"; do
# get letters
string=$(echo "$i" | grep -oE '[A-Z]+')
# get number
number=$(echo "$i" | grep -oE '[0-9]+')
# add letter in array
strings+=("${string}")
# add number in array
numbers+=("${number}")
done
# echo "${strings[*]}"
# echo "${numbers[*]}"
# Read CSV file
declare -A hash_file=()
declare word=
declare key=
declare n=
# For each line
while IFS=, read -r word n key; do
# add (key,word) tuple in hash
hash_file["${key}"]="${word}"
done < "${filename}"
# get string arrau length
declare -ir strings_len=${#strings}
declare -i  idx=0
declare letter=
declare letters=
# For index position in string array
while [[ ${idx} -le ${strings_len} ]]; do
# get string from string array
string="${strings[$idx]}"
# get number from number array
number="${numbers[$idx]}"
# get associated letter in word from hash
letter="${hash_file[${string}]:${number}-1:1}"
# add letter to letters string
letters+="${letter}"
# next index
idx+=1
done
# print result
echo "letters='${letters}'"

最新更新