如何自动创建文件?

如何自动创建文件?

我正在尝试创建一个脚本,该脚本可以:

  • 查找名称包含“foobar”的文件
  • 在此文件上执行脚本,输出必须存储在新的 CSV 文件中,该文件是自动创建的,并且与搜索的文件同名。唯一的区别是扩展名更改为 CSV。

这是我的剧本。 :

#!/bin/bash

# search for file containing "foobar" as a name in the directory
for file in /home/user/Documents/* ;
do 

if [[ "$file" == *"$foobar"* ]]; then
touch  /home/user/Documents/collectCSV/csv1.csv
# executing script of modelising foobar file ==> extract some data from $foobar file and insert it in the
# created file csv1.csv
/home/user/scriptModelise.pl  $file >> /home/user/Documents/collectCSV/csv1.csv


else 
echo "foobar file not found" 
fi

done

问题是这种创建文件的方法是静态的。我没有成功地自动创建文件。我的意思是,当它找到 foobar 文件时,它将在将创建的新文件中进行建模。

有什么帮助吗?

答案1

更容易使用(请注意,当您像这样不加引号的变量时,zsh您已经在使用语法):zsh

#! /bin/zsh -
files=(/home/user/Documents/*foobar*(N))
if (($#files)) {
  ret=0
  for f ($files) {
    /home/user/scriptModelise.pl $f > $f:h/collectCSV/$f:t:r.csv || ret=$?
  }
  exit $ret
} else {
  echo >&2 No non-hidden foobar file
  exit 1
}
  • 就像在 中一样csh$f:h是头(dirname),$f:t尾部(basename),$f:r根(删除扩展名)。
  • ((arithmetic expression))就像ksh评估算术表达式如果解析为非零值则返回 true。
  • $#array,让人想起kshs${#string}给出数组的长度(以元素数量表示)。在ksh/bash中,数组并不是真正不同的类型,您需要${#array[@]}索引${#array}0 的元素的长度(以字符数为单位)。
  • (N): glob 限定符,表示如果没有匹配则扩展为空
  • $f, $files:与其他类似 Bourne 的 shell 相反,变量不需要用引号引起来(只要它们不包含空值)。在其他 shell(ksh、bash、yash)中,您需要"$f""${files[@]}"

答案2

尝试

for file in *"$foobar"*
do
   dest="$(echo $file| sed -e 's/\(.*\)\.[^\.]*$/\1.csv/' )"
   if test -f "$file" 
   then 
       /home/user/scriptModelise.pl  "$file" >> /home/user/Documents/collectCSV/$dest
   else
     echo "no $foobar file"
   fi
done

在哪里

  • \(.*\)\.[^\.]*$捕获具有任何字符的模式,(模式结尾)后跟一个点,非点直到行尾
  • \1.csv插入找到的模式,添加 .csv

  • *"$foobar"**foobar*如果没有找到匹配的文件,将扩展为字面量(具有正确的值)。因此需要test -f "$file"

编辑:

  • \(.*\)\.[^\.]*$ (左侧:寻找模式)

分成( _ 是占位符)

  • __.*__________具有任何字符的模式(点具有特殊含义:任何字符)

  • __.*__\._______ 带有任何字符的模式,后跟一个点(转义点是普通点)

  • __.*__\.[^\.]*$具有任何字符的模式,(模式结尾)后跟一个点,非点 ( [^\.]*) 直到行尾(美元符号对于行尾是特殊的)

  • \(__\)__________捕获模式的第一部分。

  • \1.csv(右手边,做什么)

  • \1____ \1\( \)匹配第一个、\2第二个等中的内容,用于&整个模式。

答案3

使用 GNU Parallel 可以轻松做到这一点,并且可以一次处理多个文件作为奖励:

parallel /home/user/scriptModelise.pl {} ">>" {.}.csv ::: *"$foobar"*

如果没有文件匹配,这将导致错误*"$foobar"*,因此您应该首先检查这一点,或者使用find管道输入名称,或者设置 bash 的failglob选项。

相关内容