102 lines
3.3 KiB
Markdown
102 lines
3.3 KiB
Markdown
---
|
|
title: "for loops in bash / zsh shells"
|
|
date: 2020-01-12T11:54:38+01:00
|
|
draft: false
|
|
snippet_types: ["zsh", "built-ins"]
|
|
---
|
|
|
|
Looping directly in the shell is something I do at lease once a week and it's a great time saver.
|
|
Here I want to run through a concrete example of how to use for loops to mass move and rename files.
|
|
|
|
During process of getting this snippet section of my site off the ground I realize I had put a bunch
|
|
of markdown files into named directories when I could have just named the files better and done without
|
|
the directories. What I needed to do was **mv** the files out of these dirs and rename them to the
|
|
name of the dir plus add the ".en.md" extension.
|
|
|
|
Here is the old directory structure:
|
|
|
|
```shell
|
|
$ tree
|
|
.
|
|
└── snippets
|
|
├── _index.en.md
|
|
├── aws-cloud-front-inval
|
|
│ └── index.en.md
|
|
├── aws-s3-sync
|
|
│ └── index.en.md
|
|
├── ffmpeg-screen-casts
|
|
│ └── index.en.md
|
|
├── find-folder
|
|
│ └── index.en.md
|
|
├── git-better-git-add
|
|
│ └── index.en.md
|
|
├── git-log-grep
|
|
│ └── index.en.md
|
|
├── git-move-branch
|
|
│ └── index.en.md
|
|
.
|
|
.
|
|
```
|
|
|
|
To start with I preformed the operation in question a single time to prove it works:
|
|
|
|
```shell
|
|
$ mv ./who-is-using-that-port/index.en.md ./who-is-using-that-port.en.md && rm -r ./who-is-using-that-port
|
|
```
|
|
|
|
Then I copy this command to the clipboard for later and use command history pull up a
|
|
previous for loop command and switch the shell command entry external editing
|
|
in vim mode, for me **\<C-x>\<C-e>**. As we are essentially writing a quick bash script in-line we need vim
|
|
powers! While in vim if you need the file list a quick **:r !ls** does the trick.
|
|
These little efficiencies like using command history are not just faster but make it so you
|
|
don't have to remember the bash syntax.
|
|
|
|
Resulting vim buffer with the for loop:
|
|
|
|
```shell
|
|
for x in \
|
|
aws-s3-sync \
|
|
ffmpeg-screen-casts \
|
|
find-folder \
|
|
git-better-git-add \
|
|
git-log-grep \
|
|
...
|
|
git-move-branch \
|
|
vim-window-resize ; do mv ./"$x"/index.en.md ./"$x".en.md && rm -r "$x" ; done
|
|
```
|
|
|
|
Resulting new file structure:
|
|
|
|
```shell
|
|
$ tree
|
|
.
|
|
└── snippets
|
|
├── _index.en.md
|
|
├── aws-cloud-front-inval.en.md
|
|
├── aws-s3-sync.en.md
|
|
├── ffmpeg-screen-casts.en.md
|
|
├── find-folder.en.md
|
|
├── git-better-git-add.en.md
|
|
├── git-log-grep.en.md
|
|
├── git-move-branch.en.md
|
|
.
|
|
.
|
|
```
|
|
|
|
Perfect, all files have been renamed properly and the empty directories deleted. This technique has
|
|
lots of other applications besides moving and renaming files. Earlier this week while debugging api
|
|
at work I dumped bunch of json responses into a file so I could search for translation key.
|
|
|
|
```shell
|
|
$ for x in \
|
|
https://api.poeditor.com/v2/download/file/xxx \
|
|
https://api.poeditor.com/v2/download/file/xxx \
|
|
https://api.poeditor.com/v2/download/file/xxx \
|
|
https://api.poeditor.com/v2/download/file/xxx \
|
|
https://api.poeditor.com/v2/download/file/xxx \
|
|
https://api.poeditor.com/v2/download/file/xxx \
|
|
https://api.poeditor.com/v2/download/file/xxx \
|
|
https://api.poeditor.com/v2/download/file/xxx \
|
|
https://api.poeditor.com/v2/download/file/xxx \
|
|
https://api.poeditor.com/v2/download/file/xxx ; do curl $x >> /tmp/translations.json; done
|
|
```
|