在 shell 脚本中使用文件名的前 3 个字符作为变量

Use first 3 characters of a filename as a variable in shell script

这是我的第一个 post 所以希望我能把我的问题说清楚。

我是 shell 脚本的新手,我的任务是为 csv 文件的每一行添加一个新值。需要添加的值基于文件名的前 3 位数字。

我有点背景。我收到的 csv 文件最终被加载到分区的 oracle 表中。文件名的开头(例如 BATTESTFILE.txt)包含分区站点,因此我需要编写一个脚本来获取文件名的前 3 个字符(在此示例中为 BAT)并将其添加到每一行的末尾文件。

到目前为止我最接近的是当我将代码剥离到我需要做的最基本的事情时:

build_files()                                          
{                                                      
    OLDFILE=${filename[@]}.txt                     
    NEWFILE=${filename[@]}.NEW.txt                 
    ABSOLUTE='path/scripts/'        
    FULLOLD=$ABSOLUTE$OLDFILE                      
    FULLNEW=$ABSOLUTE$NEWFILE                      
    sed -e s/$/",${j}"/ "${FULLOLD}" > "${FULLNEW}"
}                                                      

set -A site 'BAT'                                      
set -A filename 'BATTESTFILE'                          

for j in ${site[@]};  do                               

    for i in ${filename[@]}; do                    
            build_files ${j}                       
    done                                           

done   

这里我设置了一个数组 site,因为会有 6 个 'sites',这样可以很容易地在文件传给我时向代码中添加附加内容。 filename数组也是如此。

此代码有效,但它没有我需要的那么自动化。我最近的尝试之一如下:

build_files()                                          
{                                                      
    OLDFILE=${filename[@]}.txt                     
    NEWFILE=${filename[@]}.NEW.txt                 
    ABSOLUTE='/app/dss/dsssis/sis/scripts/'        
    FULLOLD=$ABSOLUTE$OLDFILE                      
    FULLNEW=$ABSOLUTE$NEWFILE                      
    sed -e s/$/",${j}"/ "${FULLOLD}" > "${FULLNEW}"
}                                                      

set -A site 'BAT'                                      
set -A filename 'BATTESTFILE'                          

for j in ${site[@]};  do                               

    for i in ${filename[@]}; do                    
    trust=echo "$filename" | cut -c1-3             
    echo "$trust"                                  
    if ["$trust" = 'BAT']; then                    
    ${j} = 'BAT'                                   
    fi                                             
    build_files ${j}                               
    done                                           
done  

我在研究时通过 Whosebug 上的另一个问题找到了代码 trust=echo "$filename" | cut -c1-3,但它似乎对我不起作用。我在 echo 中添加以测试 trust 持有的内容,但它是空的。

我收到 2 个错误: 第 17 行 - BATTESTFILE:未找到 第 19 行 - 测试:] 缺失

对于冗长的问题,我们深表歉意。希望它包含有用的信息并显示我已采取的步骤。有任何问题,请评论。非常感谢任何帮助或指导。谢谢。

如果您是 shell 的新手,请尽量避免使用数组。
在 if 语句中,在 [ 和 ] 字符前后使用空格。 习惯用 {} 包围您的 shell 变量,例如 ${trust}

我不知道你是如何填充你的数组的,当数组被硬编码时,尝试用 te 替换 网站=文件1 SITE="${SITE} file2"

而且你必须告诉 unix 你想用 $(..) 计算右侧(比反向更好):

trust=$(echo "${filename}" | cut -c1-3)

可以在 Google

找到一些指南和语法帮助

只需使用 shell parameter expansion:

$ var=abcdefg
$ echo "${var:0:3}"
abc

假设您使用的是相当有能力的 shell,例如 bash 或 ksh,例如

以防万一它现在或将来对其他人有用,我使用下面的方法让我的代码按预期工作。感谢下面的 Walter A 对我的主要问题的回答,即从文件名中获取前 3 个字符并将它们用作变量。

这给了我所需的输出,即获取文件名的前 3 个字符,并将它们添加到我的 csv 文件中每一行的末尾。

## Get the current Directory and file name, create a new file name
build_files()                                                                   
{                                                                               
    OLDFILE=${i}.txt                                                        
    NEWFILE=${i}.NEW.txt                                                    
    ABSOLUTE='/app/dss/dsssis/sis/scripts/'                                 
    FULLOLD=$ABSOLUTE$OLDFILE                                               
    FULLNEW=$ABSOLUTE$NEWFILE 

## Take the 3 characters from the filename and 
## add them onto the end of each line in the csv file.

    sed -e s/$/";${j}"/ "${FULLOLD}" > "${FULLNEW}"                         
}                                                                               

## Loop to take the first 3 characters from the file names held in
## an array to be added into the new file above  

set -A filename 'BATTESTFILE'                             

    for i in ${filename[@]}; do                                             
    trust=$(echo "${i}" | cut -c1-3)                                        
    echo "${trust}"                                                         
    j="${trust}"                                                            
    echo "${i} ${j}"                                                        
    build_files ${i} ${j}                                                   

done                                                                            

希望这对其他人有用。