Linux BASH 中带空格的文件名

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3967707/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 23:43:43  来源:igfitidea点击:

File names with spaces in BASH

linuxbash

提问by finemann

I'm trying to write script that'll crop and resize large photos into HD Wallpapers.

我正在尝试编写脚本,将大照片裁剪和调整为高清壁纸。

#! /bin/bash


for i in `ls *.jpg`
do
    width=`identify -format '%w' $i`
    height=`identify -format '%h' $i`

    if [ `echo "$width/$height > 16/9" | bc -l` ]
    then
        exec `convert $i -resize 1920 -gravity Center -crop '1920x1080+0+0' +repage temp`
    else
        exec `convert $i -resize x1080 -gravity Center -crop 1920x1080+0+0 +repage temp`
    fi

    rm $i
    mv temp $i
done

But it seems that the script has problems with file names having spaces (like Tumble Weed.jpg). How can I fix this?

但似乎该脚本在文件名包含空格(如 Tumble Weed.jpg)方面存在问题。我怎样才能解决这个问题?

采纳答案by P Shved

First, you don't need ls. By using lsin backtics, you implicitly make bash parse a string into a list, which splits by whitespaces. Instead, make bash generate the list and separate it without such quirks:

首先,你不需要ls. 通过ls在 backtics 中使用,您可以隐式地让 bash 将一个字符串解析为一个列表,该列表由空格分割。相反,让 bash 生成列表并将其分开,没有这样的怪癖:

Also, you need to enclose all $iusages into quotes, to make bash substitute it as a whole, not as a string split to separate words.

此外,您需要将所有$i用法括在引号中,以使 bash 将其作为一个整体替换,而不是将其作为字符串拆分以分隔单词。

Here's the script that demonstrates both ideas:

这是演示这两种想法的脚本:

for i in *.jpg ; do 
  echo "$i";
done

回答by Pablo Santa Cruz

Use double quotes around file names. Like this:

在文件名周围使用双引号。像这样:

width=`identify -format '%w' "$i"`

Please note the double quotes around "$i".

请注意周围的双引号"$i"

回答by aioobe

I would recommend to write the for-line like this:

我建议像这样编写 for 行:

for i in *.jpg

and encapsulate $iin double-quotes: "$i".

$i用双引号括起来:"$i".



If you insist on the

如果你坚持

`ls *.jpg`

style, (if you for instance get your file-names from a more complex command) you could try setting IFSto \n:

样式,(例如,如果您从更复杂的命令中获取文件名),您可以尝试设置IFS\n

IFS='\n'

Compare these two executions:

比较这两个执行:

$ for f in `ls *`; do echo $f; done
hello
world
test

$ IFS='\n'; for f in `ls *`; do echo $f; done
hello world
test

回答by jdehaan

Use read to circumvent the problem with spaces. It looks a bit unnatural to write the loop like this but it works better:

使用 read 来规避空格问题。像这样编写循环看起来有点不自然,但效果更好:

find . -type f -iname "*.jpg" | while read i
do
    # your original code inside the loop using "$i" instead of $i
done

with -inameyou also get the jpg files that might have an extension with different casing like .JPG. "i" in "iname" means ignore casing.

-iname你也可以得到,可能有不同的外壳如.jpg扩展名的JPG文件。“iname”中的“i”表示忽略大小写。

回答by Adam Outler

 #! /bin/bash 
 mkfifo ./lsOutput
 ls -1 *.jpg > ./lsOutput
    while read line  
    do 

    width=`identify -format '%w' "$line"` 
    height=`identify -format '%h' "$line"` 

    if [ `echo "$width/$height > 16/9" | bc -l` ] 
    then 
        exec `convert "$line" -resize 1920 -gravity Center -crop '1920x1080+0+0' +repage temp` 
    else 
        exec `convert "$line" -resize x1080 -gravity Center -crop 1920x1080+0+0 +repage temp` 
    fi 

    rm "$line"
    mv temp "$line"
 done<./lsOutput

回答by Frank Koenen

In bash, use string replacement with find:

在 bash 中,使用字符串替换find

${string//substring/replacement}
Replace all matches of $substringwith $replacement.

${string//substring/replacement}
替换的所有比赛$substring$replacement

so this works:

所以这有效:

find . -type f -name '*.jpg' | while read i ; do /bin/mv -f "$i" ${i// /_}; done

回答by Alfred Gauf

I forgot to add the link if you want to downloadas txt file

如果你想下载为txt文件,我忘记添加链接了

or just copy and paste this text as needed

或根据需要复制并粘贴此文本

FIRST INSTALL

首次安装

apt-get install chromium-browser

apt-get install omxplayer

apt-get install terminator

apt-get install nano (if not already installed)

apt-get install zenity (if not already installed)

THEN CREATE A BASH SCRIPT OF ALL OF THESE PERSONALLY WRITTEN SCRIPTS.

然后创建所有这些个人编写的脚本的 BASH 脚本。

MAKE SURE THAT EVERY SHELL SCRIPT IS A .sh FILE ENDING EACH ONE OF THESE IS SCRIPTED TO OPEN UP A DIRECTORY FOR YOU TO FIND AND PICK WHAT YOU WANT.

确保每个 Shell 脚本都是一个 .sh 文件,以这些脚本结尾的每个脚本打开一个目录供您查找和选择您想要的内容。

IT RUNS A BACKGROUND TERMINAL & ALLOWS YOU TO CONTROL THE SONG OR MOVIE.

它运行后台终端并允许您控制歌曲或电影。

MOVIE KEYS ARE AS FOLLOWS; p or space bar for pause, q for quit, - & + for sound up and down, left arrow and right arrow for skipping forward and back.

电影键如下;p 或空格键用于暂停,q 用于退出,-&+ 用于上下声音,向左箭头和向右箭头用于向前和向后跳过。

MUSIC PLAYER REALLY ONLY HAS A SKIP SONG AND THAT IS CTRL+C AND IF THAT IS THE LAST SONG OR ONLY SONG THEN IT SHUTS DOWN AND THE TERMINAL GOES AWAY.

音乐播放器真的只有一首跳过歌曲,那就是 CTRL+C,如果这是最后一首歌曲或唯一一首歌曲,那么它会关闭并且终端消失。

****INSTRUCTIONS TO MAKE THE SCRIPTS****

****制作脚本的说明****

  • OPEN UP A TERMINAL

  • CD TO THE DIRECTORY YOU WANT THE SCRIPTS TO BE

    cd /home/pi/Desktop/
    
  • OPEN UP THE NANO EDITOR WITH THE TITLE OF SHELL YOU WANT

    sudo nano Movie_Player.sh
    
  • INSIDE NANO, TYPE OR COPY/PAST (REMEMBER THAT IN TERMINAL YOU NEED TO CTRL+SHIFT+V) THE SCRITP

  • SAVE THE DATA WITH CTRL+O

    ctrl+o
    
  • HIT ENTER TO SAVE AS THAT FILE NAME OR DELETE THE FILE NAME THEN TYPE NEW ONE JUST MAKE SURE IT ENDS IN .sh THEN HIT ENTER

  • NEXT YOU NEED TO SUDO CHMOD IT WITH +X TO MAKE IT CLICKABLE AS A BASH

    sudo chmod +x Movie_Player.sh
    
  • FINALLY RUN IT TO TEST EITHER BY DOUBLE CLICKING IT AND CHOOSING "EXECUTE IN TERMINAL" OR BY ./ IT IN TERMINAL

    ./Movie_Player.sh
    
  • 打开终端

  • CD 到您想要脚本的目录

    cd /home/pi/Desktop/
    
  • 使用您想要的外壳标题打开纳米编辑器

    sudo nano Movie_Player.sh
    
  • 在 NANO 中,键入或复制/粘贴(请记住,在终端中您需要按 CTRL+SHIFT+V)脚本

  • 使用 CTRL+O 保存数据

    ctrl+o
    
  • 按回车键保存为该文件名或删除文件名,然后输入新的文件名,确保它以 .sh 结尾,然后按回车键

  • 接下来,您需要使用 +X SUDO CHMOD IT 使其可作为 BASH 单击

    sudo chmod +x Movie_Player.sh
    
  • 最后运行它以通过双击它并选择“在终端中执行”或通过 ./ 它在终端中进行测试

    ./Movie_Player.sh
    

YOU ARE NOW GOOD TO PICK A MOVIE OR SELECT A SONG OR ALBUM AND ENJOY!

您现在可以选择电影或选择歌曲或专辑并享受!

**** ALL OF THESE SCRIPTS ACCOUNT FOR SPACES IN THE FILENAME

**** 所有这些脚本都占文件名中的空格

SO YOU CAN ACCESS "TOM PETTY" OR "SIXTEEN STONE" WITHOUT NEEDING THE " _ " BETWEEN THE WORDS.

因此,您可以访问“TOM PETTY”或“Sixe Stone”而无需单词之间的“_”。

-------WATCH A MOVIE SCRIPT ------- (

-------看电影剧本 ------- (

#!/bin/bash

FILE=`zenity --title "Pick a Movie" --file-selection`

for FILE in "${FILE[0]}"

do
     omxplayer "${FILE[0]}"
done

--------LISTEN TO A SONG -------

--------听一首歌 -------

#!/bin/bash

FILE=`zenity --title "Pick a Song" --file-selection`

for FILE in "${FILE[0]}"

do
     play "${FILE[0]}"
done

--------LISTEN TO AN ALBUM ---------- SONGS IN ORDER

--------听专辑 ---------- 按顺序听歌曲

#!/bin/bash

DIR=`zenity --title "Pick a Album" --file-selection --directory` 

for DIR in "${DIR[0]}"

do
  cd "${DIR[0]}" && find . -type f -name '*.ogg' -o -name '*.mp3' | sort --version-sort | while read DIR; do
  play "$DIR"
  done
done

--------LISTEN TO AN ALBUM WITH SONGS IN RANDOM ORDER --------

--------听一张随机歌曲的专辑--------

#!/bin/bash

DIR=`zenity --title "Pick a Album" --file-selection --directory` 

for DIR in "${DIR[0]}"

do
  cd "${DIR[0]}" && find . -type f -name '*.ogg' -o -name '*.mp3' | while read DIR; do
  play "$DIR"
  done
done