首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Bash:用模算法检查子字符串增量

Bash:用模算法检查子字符串增量
EN

Stack Overflow用户
提问于 2021-01-07 14:29:30
回答 2查看 81关注 0票数 0

我有一个文件名列表,其中包含一个6个数字的子字符串,表示HHMMSS,HH: 2位数小时,MM: 2位数分钟,SS: 2位数秒。

如果文件列表是有序的,增量应该是30分钟的步骤,也就是说,第一个子字符串应该是000000,然后是003000、010000、013000、……和233000。

我想检查没有缺少任何文件,迭代文件列表,检查这些子字符串是否都没有丢失。我的方法:

代码语言:javascript
复制
string_check=000000
for file in ${file_list[@]}; do
  if [[ ${file:22:6} == $string_check ]]; then
    echo "Ok"
  else
    echo "Problem: an hour (file) is missing"
    exit 99
  fi
  string_check=$((string_check+3000)) #this is the key line
done

最后一行的前一行是关键。它应该被格式化为6位,我知道如何做,但我想增加时间像一个时钟,或更具体的话,模块化算术模块60。怎样才能做到呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-01-07 15:10:09

假设:

  • 所有的6位字符串都是xx[03]0000格式(即,必须是一个偶数的0030分钟,而不是秒)
  • ,如果有像xx1529这样的字符串.这些将被忽略(请参见答案的下半部分-使用comm --以解决OP关于这些类型的字符串是错误的注释)

我们可以使用序列生成器生成所有所需的字符串,而不是尝试对字符串的MM (分钟)部分执行一串MM数学运算:

代码语言:javascript
复制
$ for string_check in {00..23}{00,30}00; do echo $string_check; done
000000
003000
010000
013000
... snip ...
230000
233000

虽然OP应该能够将其添加到当前代码中,但我认为我们可以更进一步,查看所有文件名的预解析,将6位字符串拉到一个关联数组中(即6位字符串作为索引),例如:

代码语言:javascript
复制
unset      myarray
declare -A myarray

for file in ${file_list}
do
    myarray[${file:22:6}]+=" ${file}"       # in case multiple files have same 6-digit string
done

使用序列生成器作为我们的逻辑的驱动程序,我们可以这样将它们结合在一起:

代码语言:javascript
复制
for string_check in {00..23}{00,30}00
do
    [[ -z "${myarray[${string_check}]}" ]] &&
    echo "Problem: (file) '${string_check}' is missing"
done

注意事项:OP可以决定进程是否应该完成所有字符串的检查,或者是否应该对第一个缺少的字符串进行exit (根据OP的当前代码)。

使用comm比较两个字符串列表的一个想法:

代码语言:javascript
复制
# display sequence generated strings that do not exist in the array:

comm -23 <(printf "%s\n" {00..23}{00,30}00) <(printf "%s\n" "${!myarray[@]}" | sort)

# OP has commented that strings not like 'xx[03]000]` should generate an error;
# display strings (extracted from file names) that do not exist in the sequence

comm -13 <(printf "%s\n" {00..23}{00,30}00) <(printf "%s\n" "${!myarray[@]}" | sort)

其中:

  • comm -23 -仅显示第一个“文件”中不存在于第二个“文件”中的行(即缺少xx[03]000)
  • comm -13格式的序列)--仅显示第一个“文件”中不存在的第二个“文件”中的行(即不具有格式xx[03]000)

的字符串的文件名)。

然后,可以将这些列表用作循环的输入,或者根据需要传递给xargs进行额外处理;记住,comm -13输出将显示数组的索引,而数组的相关内容将包含从其中派生6位数字字符串的原始文件的名称。

票数 1
EN

Stack Overflow用户

发布于 2021-01-07 16:54:03

使用POSIX shell可以轻松地做到这一点,并且只使用内置的:

代码语言:javascript
复制
#!/usr/bin/env sh

# Print an x for each glob matched file, and store result in string_check
string_check=$(printf '%.0sx' ./*[0-2][0-9][03]000*)

# Now string_check length reflects the number of matches
if [ ${#string_check} -eq 48 ]; then
  echo "Ok"
else
  echo "Problem: an hour (file) is missing"
  exit 99
fi

另一种选择是:

代码语言:javascript
复制
#!/usr/bin/env sh

if [ "$(printf '%.0sx' ./*[0-2][0-9][03]000*)" \
     = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' ]; then
  echo "Ok"
else
  echo "Problem: an hour (file) is missing"
  exit 99
fi
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65614277

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档