linux - 如何测试文件中的某些字符

标签 linux bash sed

我目前正在运行一个带有 if 语句的脚本。在运行脚本之前,我想确保作为第一个参数提供的文件具有特定字符。

如果文件在某些​​位置没有这些特定字符,那么命令行上的输出将是 else "File is Invalid"

要使 if 语句为真,文件需要在 Field 1 line 1 中至少有一个 hyphen 和至少一个 comma 在 Field one Line one。

我将如何创建一个 if 语句,也许还有一个测试命令来验证那些特定字符是否存在?

谢谢

我是 Linux/Unix 的新手,这是我的作业,所以我没有真正尝试过任何东西,只是集思广益可能的解决方案。

function usage
{
  echo "usage: $0 filename ..."
  echo "ERROR: $1"
}

if [ $# -eq  0 ]
then
  usage "Please enter a filename"
else
  name="Yaroslav Yasinskiy"
  echo $name
  date
  while [ $# -gt 0 ]
  do
    if [ -f $1 ]
    then
      if            <--------- here is where the answer would be
      starting_data=$1
      echo
      echo $1
        cut -f3 -d, $1 > first
        cut -f2 -d, $1 > last
        cut -f1 -d, $1 > id
        sed 's/$/:/' last > last1
        sed '/last:/ d' last1 > last2
        sed 's/^ *//' last2 > last3
        sed '/first/ d' first > first1
        sed 's/^ *//' first1 > first2
        sed '/id/ d' id > id1
        sed 's/-//g' id1 > id2
        paste -d\ first2 last3 id2 > final
        cat final
        echo ''
    else
      echo
      usage "Coult not find file $1"
    fi
    shift
  done
fi

最佳答案

回答您的直接问题:

For the if statement to be true, the file needs to have at least one hyphen in Field 1 line 1 and at least one comma in Field one Line one.

How would I create an if statement with perhaps a test command to validate those certain characters are present?

Bash 提供了您需要的所有工具。虽然您可以调用 awk,但您实际上只需要将文件的第一行读入两个变量(例如 ab),然后然后使用 [[ $a =~ regex ]]regex 是一个扩展正则表达式的地方,它验证第一个字段(包含在 $a) 中包含 '-'','

有关 [[ =~ ]] 表达式的详细信息,请参阅 bash(1) - Linux manual page在标记为 [[ expression ]] 的部分下。

让我们从阅读开始。当您提供两个变量时,read 将读取第一个字段(基于 IFS 给出的正常分词(Internal Field Separator,默认$'[\t\n]' - 空格、制表符、换行符))。因此,通过执行 read -r a b,您将第一个字段读入 a 并将该行的其余部分读入 b(您不关心 b 用于测试)

你的 regex 可以是 ([-]+.*[,]+|[,]+.*[-]+) 这是一个 (x|y),例如xy 表达式,其中 x[-]+.*[,]+(一个或多个 '-' 和一个或多个 ','), 你的 y[,]+.*[-]+(一个或多个 ',' 和一个或多个 '-')。因此,通过使用 '|',您的正则表达式将接受 逗号,然后是零个或多个字符以及 连字符连字符和零个或多个字符,然后是第一个字段中的逗号

你是怎么读这行的?使用简单的重定向,例如

read -r a b < "$1"

所以你的脚本中的条件测试看起来像这样:

if [ -f $1 ]
then
  read -r a b < "$1"
  if [[ $a =~ ([-]+.*[,]+|[,]+.*[-]+) ]]    # <-- here is where the ...
  then
    starting_data=$1
    ...
  else
    echo "File is Invalid" >&2   # redirection to 2 (stderr)
  fi
else
  echo
  usage "Coult not find file $1"
fi
shift
...

示例测试文件

$ cat valid
dog-food, cat-food, rabbit-food
50lb      16lb      5lb

$ cat invalid
dogfood, catfood, rabbitfood
50lb      16lb      5lb

示例使用/输出

$ read -r a b < valid
if [[ $a =~ ([-]+.*[,]+|[,]+.*[-]+) ]]; then
  echo "file valid"
else 
  echo "file invalid"
fi
file valid

对于没有特定字符的文件:

$ read -r a b < invalid
if [[ $a =~ ([-]+.*[,]+|[,]+.*[-]+) ]]; then
  echo "file valid"
else 
  echo "file invalid"
fi
file invalid

现在你真的必须集中精力消除至少十几个子壳的生成,你调用 cut 3 次,sed 7 次,paste 一次然后 cat。正如我的评论中所提到的,尽管您正在考虑需要做什么并使其正常工作是件好事,但无论何时循环,您都希望尽可能减少生成的子 shell 的数量。我怀疑正如@Mig 回答的那样,awk 将是可能消除所有 12 个子 shell 的合适工具,只需调用 awk 即可替换它。

关于linux - 如何测试文件中的某些字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57212906/

相关文章:

linux - 将文件拆分到新文件夹中

bash - 如何使用 BSD/OS X sed 在匹配后删除/删除 X 行

regex - 用sed删除字符

c - 如何在procfs中执行顺序读取?

linux - 如何在中断处理程序中进行上下文切换?

linux - 为 ptrace_scope 禁用 AppArmor for Docker

bash - 如何告诉 rsync 仅在目标目录存在时运行?

BASH 脚本 : Explode string and save to file

bash - 如何使用 aws cli 命令仅显示来自 s3 存储桶的目录

bash - 用于抓取数据并进行减法的 shell 脚本