Bash从字符串

时间:2018-06-11 10:45:43

标签: string bash replace

我有一个这样的字符串:

myString='value1|value57|value31|value21'

我发了一个名为values_to_remove.txt的文件,其中包含一个值列表,每行一个

values_to_remove.txt

value1
value31

在bash中,如何删除" values_to_remove.txt"中包含的值?从字符串开始,考虑到值是由管道分隔的,当然如果我删除了一个值,我必须删除前面和后面的管道(如果有的话)。

我已经在python中实现了这个并且从bash调用了python脚本,但是我需要使用一行命令直接在bash中执行此操作,而不是使用小脚本,否则我已经可以使用我的小python脚本了。

这是python代码

myString = 'value1|value2|value3|value4'
arrString = myString.split("|")

with open("myfile.txt", encoding="utf-8") as file:
   for l in file:
       if  l in arrString:
           arrString.remove(l)

myNewString = "|".join(arrString)

请注意:由pipe分隔的值可以是任何字符串。

谢谢

3 个答案:

答案 0 :(得分:3)

您可以使用此awk

awk -v str="$myString" 'BEGIN {
   n = split(str, a, /\|/)
}
{
   val[$1]
}
END {
   for (i=1; i<=n; i++)
      if (!(a[i] in val))
         s = (s == "" ? "" : s "|") a[i]
   print s
}' values_to_remove.txt

value57|value21
  • awk首先在split上使用split函数与|输入字符串
  • 它将要删除的所有值存储在另一个数组val
  • 在结束块中,它循环遍历split数组并构建一个字符串,如果在要删除的数组中找不到值。

答案 1 :(得分:1)

这是一个bash解决方案(if语句是一个运行时优化,在没有匹配的情况下跳过重新配置,感谢@Inian):

for val in value1 value31; do
    if [[ "$mystring" =~ \|$val|$val\| ]]; then
        mystring=${mystring/$BASH_REMATCH/}     
    fi
done

这将在纯bash中查找与|valuevalue|匹配的第一个正则表达式并将其删除。请注意,您可以同时匹配两者,因为这样您将删除太多的分隔符。如果有可能没有分隔符,则需要在每个管道后使用?(可能只是第二个就足够了)。

您还可以避免使用正则表达式,只是尝试删除前导管和后导管:

for val in value1 value31; do 
    mystring=${mystring/|$val/};
    mystring=${mystring/$val|/}; 
done

如果你真的需要,所有这些都可以写在一行:

 for val in value1 value31; do [[ "$mystring" =~ \|$val|$val\| ]]; mystring=${mystring/$BASH_REMATCH/}; done

答案 2 :(得分:0)

纯粹的bash解决方案:

#!/usr/bin/env bash

# Define the location of the values-to-be-removed file
: ${PATH_TO_FILE:=${1:-"./values_to_remove.txt"}}

# Define the string we will be working with
: ${MY_STRING:=${2:-"value1|value57|value31|value21"}}

# Process all entries in PATH_TO_FILE, one by one
while read -r substring || [[ -n "$line" ]]; do

  # Remove "substring|" from the beginning of MY_STRING
  MY_STRING=${MY_STRING#${substring}|}

  # Remove "|substring" from the rest of MY_STRING
  MY_STRING=${MY_STRING//|${substring}}

done < "${PATH_TO_FILE}"

# Return the results
echo ${MY_STRING}

为什么我们......

  • 使用${VAR_NAME:=${1:-"DEFAULT_VALUE"}}表示法 - 允许用户通过环境变量或脚本参数自定义脚本的输入。基本上,这种表示法说:

    • 如果存在VAR_NAME环境变量,则使用它;
    • 如果VAR_NAME不存在,则将VAR_NAME设置为脚本的第一个参数的值;
    • 如果第一个参数也不存在,则将VAR_NAME设置为DEFAULT_VALUE。
  • 使用read -r substring || [[ -n "$line" ]]读取文件? - read允许我们逐行阅读./values_to_remove.txt文件的内容。 [[ -n "$line" ]]位用于捕获文件中的最后一行(如果它不以换行符结尾)。

<强>参考